<script>
import { computed, defineComponent, ref, watch } from 'vue';
import FanIcon from '../icon/icon.vue';
import { createNamespace, transformStyleSize } from '../utils';

export default defineComponent({
  name: createNamespace('Input')[0],
  components: { FanIcon },
  options: {
    // https://uniapp.dcloud.io/matter.html#mp
    virtualHost: true,
  },
  props: {
    readonly: {
      type: Boolean,
      default: false,
    },
    maxlength: {
      type: Number,
      default: -1,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    modelValue: {
      type: [String, Number],
      default: '',
    },
    prefixIcon: String,
    prefixColor: {
      type: String,
      default: 'var(--fan-black-2)',
    },
    prefixSize: {
      type: [String, Number],
      default: 17,
    },
    suffixIcon: String,
    suffixColor: {
      type: String,
      default: 'var(--fan-black-2)',
    },
    suffixSize: {
      type: [String, Number],
      default: 17,
    },
    // TODO: 小程序特有属性渐进增强
    type: {
      type: String,
      default: 'text',
    },
    inputStyle: String,
    placeholder: String,
    autofocus: Boolean,
    placeholderColor: {
      type: String,
      default: '#C4C7CC',
    },
    clearable: {
      type: Boolean,
      default: false,
    },
    clearIcon: {
      type: String,
      default: 'close-circle-fill',
    },
    label: String,
    labelStyle: String,
    border: {
      type: Boolean,
      default: false,
    },
  },
  emits: [
    'update:modelValue',
    'input',
    'change',
    'confirm',
    'blur',
    'focus',
    'clear',
  ],
  setup(props, context) {
    const theStyle = computed(() => {
      return `--fan-input-placeholder-color:${props.placeholderColor};`;
    });
    const inStyle = computed(() => transformStyleSize(props.inputStyle));
    const labStyle = computed(() => transformStyleSize(props.labelStyle));

    const innerValue = ref('');
    watch(innerValue, (val) => {
      if (val !== props.modelValue) context.emit('update:modelValue', val);
      context.emit('input', val);
    });
    watch(
      () => props.modelValue,
      (val) => {
        if (val !== innerValue.value) innerValue.value = val;
      },
      { immediate: true },
    );

    const handleInput = (e) => {
      innerValue.value = e.target.value;
    };
    const handleChange = (e) => {
      context.emit(e, innerValue.value);
    };
    const onClear = () => {
      innerValue.value = '';
      context.emit('clear', '');
    };
    const focused = ref(false);
    const onFocus = (e) => {
      focused.value = true;
      context.emit('focus', e);
    };
    const onBlur = (e) => {
      // 否则聚焦状态直接点击清除按钮 可能因为元素消失而失效
      setTimeout(() => {
        focused.value = false;
      }, 300);
      context.emit('blur', e);
    };

    return {
      theStyle,
      inStyle,
      labStyle,
      innerValue,
      focused,
      handleInput,
      handleChange,
      onClear,
      onFocus,
      onBlur,
    };
  },
});
</script>

<template>
  <div
    :style="theStyle"
    class="fan-input__wrap"
    :class="{ 'fan-hairline--bottom': border }"
  >
    <FanIcon
      v-if="prefixIcon"
      :name="prefixIcon"
      :color="prefixColor"
      :size="prefixSize"
      style="margin-right: 4px"
    />
    <div v-if="label" :style="labStyle" class="fan-input__label">
      {{ label }}
    </div>

    <input
      class="fan-input"
      :class="[
        { 'fan-input--disabled': disabled },
        { 'fan-input--unreal': disabled || readonly },
      ]"
      :type="type"
      :value="innerValue"
      :maxlength="maxlength"
      :readonly="readonly"
      :disabled="disabled || readonly"
      :autofocus="autofocus ? 'autofocus' : ''"
      :style="inStyle"
      :placeholder="placeholder"
      :placeholder-style="`color:${placeholderColor};`"
      @blur="onBlur"
      @focus="onFocus"
      @input="handleInput"
      @change="handleChange('change')"
      @keyup.enter="handleChange('confirm')"
      @confirm="handleChange('confirm')"
    />

    <FanIcon
      v-if="clearable && innerValue && focused"
      :name="clearIcon"
      :color="suffixColor"
      :size="suffixSize"
      @click="onClear"
    />
    <FanIcon
      v-if="suffixIcon"
      :name="suffixIcon"
      :color="suffixColor"
      :size="suffixSize"
      style="margin-right: 4px"
    />
  </div>
</template>

<style lang="less">
.fan-input {
  font-size: inherit;
  height: 100%;
  line-height: inherit;
  font-weight: inherit;
  letter-spacing: inherit;
  color: inherit;
  margin: 0;
  padding: 0 4px;
  flex: 1;
  overflow: hidden;
  background: transparent;
  border: 0;
  outline: none;

  &::placeholder {
    color: var(--fan-input-placeholder-color);
  }

  &--disabled {
    opacity: var(--fan-disabled-opacity);
    cursor: not-allowed;
  }

  &--unreal {
    pointer-events: none;
  }

  &__wrap {
    flex: 1;
    min-width: 0;
    height: 40px;
    display: flex;
    align-items: center;
    padding: 0 10px;
  }

  &__label {
    padding-right: 4px;
  }
}
</style>
